from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Dict, List

from flask import Flask, jsonify, render_template, request


APP_PORT = 21127
DATA_FILE = Path("data/results.json")
MAX_RESULTS = 200


app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False


def _ensure_data_file() -> None:
    DATA_FILE.parent.mkdir(parents=True, exist_ok=True)
    if not DATA_FILE.exists():
        DATA_FILE.write_text("[]", encoding="utf-8")


def load_results() -> List[Dict[str, Any]]:
    _ensure_data_file()
    try:
        return json.loads(DATA_FILE.read_text(encoding="utf-8"))
    except json.JSONDecodeError:
        return []


def save_results(results: List[Dict[str, Any]]) -> None:
    _ensure_data_file()
    DATA_FILE.write_text(json.dumps(results, ensure_ascii=False, indent=2), encoding="utf-8")


def build_stats(results: List[Dict[str, Any]]) -> Dict[str, Any]:
    times = [r["time"] for r in results]
    stats: Dict[str, Any] = {
        "count": len(times),
        "last": times[-1] if times else None,
        "average": round(sum(times) / len(times), 2) if times else None,
        "best": round(min(times), 2) if times else None,
        "recent": list(reversed(results[-5:])),
        "top": sorted(results, key=lambda r: r["time"])[:5],
    }
    return stats


@app.get("/")
def index():
    stats = build_stats(load_results())
    return render_template("index.html", initial_stats=stats)


@app.get("/api/results")
def get_results():
    stats = build_stats(load_results())
    return jsonify({"ok": True, "data": stats})


@app.post("/api/results")
def save_result():
    payload = request.get_json(silent=True) or {}
    reaction_time = payload.get("reaction_time")
    if not isinstance(reaction_time, (int, float)):
        return jsonify({"ok": False, "error": "reaction_time must be numeric"}), 400

    reaction_time = float(reaction_time)
    if reaction_time <= 0 or reaction_time > 10000:
        return jsonify({"ok": False, "error": "reaction_time out of range"}), 400

    record = {
        "time": round(reaction_time, 2),
        "ip": request.remote_addr or "unknown",
        "ts": datetime.now(timezone.utc).isoformat(),
    }

    results = load_results()
    results.append(record)
    if len(results) > MAX_RESULTS:
        results = results[-MAX_RESULTS:]
    save_results(results)

    stats = build_stats(results)
    return jsonify({"ok": True, "data": stats, "record": record})


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=APP_PORT, debug=False)
